package com.itheima.app.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.itheima.app.interceptor.UserHolder;
import com.itheima.app.mq.MovementMQSend;
import com.itheima.autoconfig.oss.OssTemplate;
import com.itheima.domain.db.UserInfo;
import com.itheima.domain.mongo.Comment;
import com.itheima.domain.mongo.Movement;
import com.itheima.domain.vo.CommentVo;
import com.itheima.domain.vo.MovementVo;
import com.itheima.domain.vo.PageBeanVo;
import com.itheima.service.db.UserInfoService;
import com.itheima.service.mongo.CommentService;
import com.itheima.service.mongo.MovementService;
import com.itheima.util.ConstantUtil;
import com.sun.org.apache.regexp.internal.RE;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.annotation.Id;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.lang.invoke.VolatileCallSite;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service // spring的
public class MovementManager {

    @Reference
    private MovementService movementService;

    @Autowired
    private OssTemplate ossTemplate;

    @Reference
    private UserInfoService userInfoService;

    @Reference
    private CommentService commentService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Autowired
    private MovementMQSend movementMQSend;

    // 发布动态
    public ResponseEntity saveMovement(Movement movement, MultipartFile[] imageContent) throws IOException {
        // 1.获取登录人id
        Long userId = UserHolder.get().getId();

        // 2.将动态图片上传到oss，并返回图片url地址
        List<String> imgList = new ArrayList<>();
        if (ArrayUtil.isNotEmpty(imageContent)) {
            for (MultipartFile multipartFile : imageContent) {
                String imgUrl = ossTemplate.upload(multipartFile.getOriginalFilename(), multipartFile.getInputStream());
                imgList.add(imgUrl);
            }
        }

        // 3.封装movement对象
        movement.setId(ObjectId.get()); // 设置动态id
        movement.setUserId(userId); // 指定用户id
        movement.setMedias(imgList); // 指定动态图片列表
        movement.setSeeType(1); // 目前1.0版本还未实现
        movement.setState(0); // TODO 后台实现了华为云审核，这里代码需要修改，暂时写死审核通过
        movement.setCreated(System.currentTimeMillis());

        // 4.调用rpc完成动态发布
        movementService.saveMovement(movement);

        // 投递动态消息
        rocketMQTemplate.convertAndSend("tanhua-movement", movement.getId().toHexString());


        // 投递推荐动态的消息
        movementMQSend.movementSend(userId, movement.getId().toHexString(), MovementMQSend.MOVEMENT_PUBLISH);

        return ResponseEntity.ok(null);
    }

    // 我的动态
    public ResponseEntity findMyMovement(Integer pageNum, Integer pageSize, Long userId) {
        // 1.调用rpc完成动态详情分页查询
        PageBeanVo pageBeanVo = movementService.findMyMovementByPage(pageNum, pageSize, userId);

        // 2.将movement对象封装为movementVo
        // 2-1 根据userId查询userInfo对象 【我的动态：用户详情都是一样的】
        UserInfo userInfo = userInfoService.findById(userId);
        // 2-2 定义vo集合
        List<MovementVo> voList = new ArrayList<>();
        // 2-3 获取并遍历movement集合
        List<Movement> movementList = (List<Movement>) pageBeanVo.getItems();
        if (CollectionUtil.isNotEmpty(movementList)) {
            for (Movement movement : movementList) {

                // 2-4 封装vo对象
                MovementVo vo = new MovementVo();
                vo.setUserInfo(userInfo); // 指定用户信息
                vo.setMovement(movement); // 指定动态信息
                // 设置点赞标记
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.MOVEMENT_LIKE, userId, movement.getId()))) {
                    vo.setHasLiked(1);
                }

                // 2-5 设置到vo集合中
                voList.add(vo);
            }
        }

        // 3.返回分页对象
        // 3-1 设置voList
        pageBeanVo.setItems(voList);
        // 3-2 返回
        return ResponseEntity.ok(pageBeanVo);
    }

    // 好友动态
    public ResponseEntity findFriendMovement(Integer pageNum, Integer pageSize) {
        // 1.获取当前登录人userId
        Long userId = UserHolder.get().getId();
        // 2.调用rpc查询动态详情分页对象
        PageBeanVo pageBeanVo = movementService.findFriendMovementByPage(pageNum, pageSize, userId);

        // 3.movement封装到movementVo对象中
        // 3-1 创建voList
        List<MovementVo> voList = new ArrayList<>();
        // 3-2 获取并遍历 movementList
        List<Movement> movementList = (List<Movement>) pageBeanVo.getItems();
        if (CollectionUtil.isNotEmpty(movementList)) {
            for (Movement movement : movementList) {
                // 3-3 获得动态发布人的userId
                Long publishUserId = movement.getUserId();
                // 3-4 查询该用户的信息
                UserInfo userInfo = userInfoService.findById(publishUserId);
                // 3-5 封装vo
                MovementVo vo = new MovementVo();
                vo.setUserInfo(userInfo); // 指定用户信息
                vo.setMovement(movement); // 指定动态信息
                // 设置点赞标记
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.MOVEMENT_LIKE, userId, movement.getId()))) {
                    vo.setHasLiked(1);
                }
                // 3-6 添加到集合中
                voList.add(vo);
            }
        }

        // 4.返回分页对象
        // 4-1 设置voList
        pageBeanVo.setItems(voList);
        // 4-2 返回
        return ResponseEntity.ok(pageBeanVo);
    }

    // 推荐动态
    public ResponseEntity findRecommendMovement(Integer pageNum, Integer pageSize) {
        // 1.获取登录人userId
        Long userId = UserHolder.get().getId();
        // 2.调用rpc查询
        PageBeanVo pageBeanVo = movementService.findRecommendMovementByPage(pageNum, pageSize, userId);
        // 3.组装movementVo
        // 3-1 声明 voList
        List<MovementVo> voList = new ArrayList<>();
        // 3-2 获取动态集合
        List<Movement> movementList = (List<Movement>) pageBeanVo.getItems();
        // 3-3 遍历
        if (CollectionUtil.isNotEmpty(movementList)) {
            for (Movement movement : movementList) {
                // 获取动态发布人id
                Long publishUserId = movement.getUserId();

                // 查询用户详情
                UserInfo userInfo = userInfoService.findById(publishUserId);

                // 组装vo
                MovementVo movementVo = new MovementVo();
                movementVo.setUserInfo(userInfo);
                movementVo.setMovement(movement);

                // 设置点赞标记
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.MOVEMENT_LIKE, userId, movement.getId()))) {
                    movementVo.setHasLiked(1);
                }

                // 设置喜欢标记
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.MOVEMENT_LOVE, userId, movement.getId()))) {
                    movementVo.setHasLoved(1);
                }

                voList.add(movementVo);
            }
        }
        // 4.返回分页对象
        pageBeanVo.setItems(voList);
        return ResponseEntity.ok(pageBeanVo);
    }

    // 点赞
    public ResponseEntity saveMovementLike(String movementId) {
        // 1.获取登录人userId
        Long userId = UserHolder.get().getId();
        // 2.封装comment对象并保存
        Comment comment = new Comment();
        comment.setCreated(System.currentTimeMillis()); // 点赞时间
        comment.setCommentType(1);// 操作类型：1点赞
        comment.setPublishId(new ObjectId(movementId)); // 评论id
        comment.setUserId(userId);
        // 调用rpc保存
        Integer likeCount = commentService.saveMovementComment(comment);

        // 3.向redis中添加点赞标记  (movement_like:操作人id_动态id  = 1)
        stringRedisTemplate.opsForValue().set(StrUtil.format(ConstantUtil.MOVEMENT_LIKE, userId, movementId), "1");


        // 投递推荐动态的消息
        movementMQSend.movementSend(userId, movementId, MovementMQSend.MOVEMENT_LIKE);

        // 4.返回操作数量
        return ResponseEntity.ok(likeCount);
    }

    // 取消点赞
    public ResponseEntity deleteMovementLike(String movementId) {
        // 1.获取登录人userId
        Long userId = UserHolder.get().getId();
        // 2.调用rpc删除
        Integer likeCount = commentService.deleteMovementComment(movementId, userId, 1);
        // 3.从redis中移除点赞标记
        stringRedisTemplate.delete(StrUtil.format(ConstantUtil.MOVEMENT_LIKE, userId, movementId));

        // 投递推荐动态的消息
        movementMQSend.movementSend(userId, movementId, MovementMQSend.MOVEMENT_DISLIKE);
        // 4.返回操作数量
        return ResponseEntity.ok(likeCount);
    }

    // 喜欢
    public ResponseEntity saveMovementLove(String movementId) {
        // 1.获取登录人userId
        Long userId = UserHolder.get().getId();
        // 2.封装comment对象，并调用rpc保存
        Comment comment = new Comment();
        comment.setCreated(System.currentTimeMillis());// 操作时间
        comment.setPublishId(new ObjectId(movementId)); // 动态id
        comment.setCommentType(3); // 操作类型：喜欢
        comment.setUserId(userId);// 操作人userId
        Integer loveCount = commentService.saveMovementComment(comment);
        // 3.向redis中添加喜欢标记
        stringRedisTemplate.opsForValue().set(StrUtil.format(ConstantUtil.MOVEMENT_LOVE, userId, movementId), "1");

        // 投递推荐动态的消息
        movementMQSend.movementSend(userId, movementId, MovementMQSend.MOVEMENT_LOVE);
        // 4.返回操作数量
        return ResponseEntity.ok(loveCount);
    }

    // 取消喜欢
    public ResponseEntity deleteMovementLove(String movementId) {
        // 1.获取登录人userId
        Long userId = UserHolder.get().getId();
        // 2.调用rpc删除
        Integer loveCount = commentService.deleteMovementComment(movementId, userId, 3);
        // 3.移出redis中喜欢标记
        stringRedisTemplate.delete(StrUtil.format(ConstantUtil.MOVEMENT_LOVE, userId, movementId));
        // 投递推荐动态的消息
        movementMQSend.movementSend(userId, movementId, MovementMQSend.MOVEMENT_DISLOVE);
        // 4.返回操作数量
        return ResponseEntity.ok(loveCount);
    }

    // 根据主键查询动态详情
    public ResponseEntity findMovementById(String movementId) {
        // 1.根据动态id查询动态详情
        Movement movement = movementService.findMovementById(movementId);

        // 2.组装movementVo
        MovementVo movementVo = new MovementVo();
        // 2-1 查询userInfo
        UserInfo userInfo = userInfoService.findById(movement.getUserId());

        // 2-2 组装，注意顺序  先userInfo再  movement
        movementVo.setUserInfo(userInfo);
        movementVo.setMovement(movement);

        // 投递推荐动态的消息
        movementMQSend.movementSend(UserHolder.get().getId(), movementId, MovementMQSend.MOVEMENT_BROWSE);

        // 3.返回结果
        return ResponseEntity.ok(movementVo);
    }

    // 查询动态详情评论列表
    public ResponseEntity findMovementComment(Integer pageNum, Integer pageSize, String movementId) {
        // 1.调用 rpc 查询
        PageBeanVo pageBeanVo = commentService.findMovementCommentByPage(pageNum, pageSize, movementId);

        // 2.封装commentVo
        // 2-1 声明voList
        List<CommentVo> voList = new ArrayList<>();
        // 2-2 获取评论列表
        List<Comment> commentList = (List<Comment>) pageBeanVo.getItems();
        // 3-3遍历
        if (CollectionUtil.isNotEmpty(commentList)) {
            for (Comment comment : commentList) {
                // 查询 userInfo
                UserInfo userInfo = userInfoService.findById(comment.getUserId());

                // 组装vo
                CommentVo commentVo = new CommentVo();

                // 组装info信息
                commentVo.setAvatar(userInfo.getAvatar());
                commentVo.setNickname(userInfo.getNickname());

                // 组装comment信息
                commentVo.setId(comment.getId().toString());
                commentVo.setContent(comment.getContent());
                commentVo.setCreateDate(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(comment.getCreated())));
                // 添加到集合中
                voList.add(commentVo);

            }
        }

        // 3.返回分页对象
        pageBeanVo.setItems(voList);
        return ResponseEntity.ok(pageBeanVo);
    }

    // 发表评论
    public ResponseEntity saveMovementComment(String movementId, String content) {
        // 1.组装comment
        Comment comment = new Comment();
        comment.setCreated(System.currentTimeMillis()); // 评论时间
        comment.setPublishId(new ObjectId(movementId)); // 动态id
        comment.setContent(content); // 评论内容
        comment.setCommentType(2);// 动态评论类型
        comment.setUserId(UserHolder.get().getId());// 评论人id

        // 2.调用rpc保存
        Integer commentCount = commentService.saveMovementComment(comment);

        // 投递推荐动态的消息
        movementMQSend.movementSend(UserHolder.get().getId(), movementId, MovementMQSend.MOVEMENT_COMMENT);

        // 3.返回评论列表
        return findMovementComment(1, 8, movementId);
    }
}
